var _ = require('lodash');
var moment = require('moment');
var { request, summary, body, description, tags } = require('koa-swagger-decorator');

const globalResponseCode = require('../base/ResponseCode');
var TestRecord = require('../Models/TestRecord');
var TestRecordLog = require('../Models/TestRecordLog');
var TestReport = require('../Models/TestReport');
var Project = require('../Models/Project');
var Versoin = require('../Models/Version');
var User = require('../Models/User');
var logTool = require('../Tools/LogTool');


var testrecordResponseCode = {
  SOME_RECORD_NOT_FINISHED: { code: 50001, message: '该版本下存在未完成的提测记录,不可提测！' },
  PARAMS_USERS_ERROR: { code: 50002, message: '提测记录的成员参数错误！' },
  ILLEGAL_TEST_STATUS: { code: 50004, message: '非法的测试状态，测试状态为 测试单状态 1=产品体验中 2=测试审核中 3=产品打回 4=测试打回 5=测试审核通过（测试完成）' },
  UPDATE_TEST_STATUS_FAIL: { code: 50005, message: '修改提测记录的状态失败！' },
  TEST_RECORD_NOT_EXIST: { code: 50006, message: '提测记录不存在！' },
  TEST_RECORD_SELF_TEST_MUST_BE_PASSED: { code: 50007, message: '自测通过才能提测！' },
  UPDATE_NOT_AFFECTED: { code: 50008, message: '提测记录修改未生效：已终止、非激活状态、修改信息未变动的提测记录，修改不会生效！' },
  DELETE_FAILED: { code: 50009, message: '删除提测记录失败：已被删除、已终止的记录不可删除！不存在的记录删除失败！' },
  ONLY_DEVELOPER_CAN_CREATE: { code: 50010, message: '只有开发可提测！' },
  ONLY_ADMINISTRATOR_CAN_DELETE: { code: 50011, message: '只有管理员可删除！' },
  ONLY_CREATER_CAN_EDIT: { code: 50012, message: '只有提测创建者可编辑' },
  USER_NOT_IN_PROJECT: { code: 50013, message: '用户不在提测记录所在的项目中, 无权限操作！' },
  PM_CHECK_PASS_FAIL: { code: 50021, message: '产品审核通过失败！' },
  PM_CHECK_BACK_FAIL: { code: 50021, message: '产品打回失败！' },
  TESTER_CHECK_PASS_FAIL: { code: 50021, message: '测试审核通过失败！' },
  TESTER_CHECK_BACK_FAIL: { code: 50021, message: '测试打回失败！' },
  RECORD_VERSION_NOT_EXISTS: {code:50031, message: '提测记录的版本不存在！'},
  WEBHOOK_NOT_EXISTS:{code:50041,message:'钉钉机器人未设置'}
};

class TestSheetController {

  @request('post', '/testrecord/add')
  @tags(['TestRecord'])
  @summary('创建提测单')
  @description('只有开发可提测')
  @body({
    projectId: { type: 'int', required: true, example: 1 },
    versionId: { type: 'int', required: true, example: 1 },
    newFeatureRemark: { type: 'string', require: false, example: '新功能1 新功能2 新功能3' },
    updateRemark: { type: 'string', require: false, example: '修改点1 修改点2 修改点3' },
    adviseRemark: { type: 'string', require: false, example: '已知问题有...' },
    testPackageUrl: { type: 'string', require: true, example: 'http://mblock.com/dowmload/' },
    selfTestStatus: { type: 'int', required: true, example: 1, description: '自测状态，必填 0：通过，1：不通过' }
  })
  async addTestRecord(ctx) {
    try {
      if (ctx.session.user) {
        let user = ctx.session.user;
        if (user.roleId == 2) {
          let testRecord = ctx.request.body;
          testRecord.createUserId = user.id;
          if (!testRecord.projectId || !testRecord.versionId || !_.isInteger(testRecord.projectId) || !_.isInteger(testRecord.versionId)) {
            return ctx.body = globalResponseCode.PARAMS_ERROR;
          }
          if (!testRecord.testPackageUrl) {
            return ctx.body = globalResponseCode.PARAMS_ERROR;
          }
          if (!('selfTestStatus' in testRecord)) {
            return ctx.body = globalResponseCode.PARAMS_ERROR;
          }
          if (testRecord.selfTestStatus !== 0) {
            return ctx.body = testrecordResponseCode.TEST_RECORD_SELF_TEST_MUST_BE_PASSED;
          }
          let isUserInProject = await User.queryIsUserInProject(testRecord.projectId, user.id);
          if (!isUserInProject) {
            return ctx.body = testrecordResponseCode.USER_NOT_IN_PROJECT;
          }
          let data = await TestRecord.queryVersionTestCount(testRecord)
          if(data !=0){
            if(data==3){
              testRecord.testStatus = 1
            }else{
              testRecord.testStatus = 2
            }
          }else{
            testRecord.testStatus = 1
          }
          let testRecordId = await TestRecord.insert(testRecord, user);

          if (testRecordId !== 0) {
            let testRecordLogId = await TestRecordLog.insert(user, testRecordId, '提交测试', '');
          //  console.log('ttt',testRecordLogId)
            return ctx.body = _.merge({}, globalResponseCode.SUCCESS, { data: { id: testRecordId } });
          } else {
            return ctx.body = testrecordResponseCode.SOME_RECORD_NOT_FINISHED;
          }
        } else {
          return ctx.body = testrecordResponseCode.ONLY_DEVELOPER_CAN_CREATE;
        }
      } else {
        return ctx.body = globalResponseCode.NO_LOGIN;
      }
    } catch (error) {
      logTool.logError(ctx, error);
      console.log('error1',error)
      return ctx.body = globalResponseCode.SYSTEM_EXCEPTION;
    }
  }

  @request('delete', '/testrecord/delete')
  @tags(['TestRecord'])
  @summary('删除提测单')
  @description('1. 只有管理员可删除；2. 已终结的提测不可删除')
  @body({
    id: { type: 'int', required: true, example: 1, description: '提测记录ID' }
  })
  async deleteTestRecord(ctx) {
    try {
      if (ctx.session.user) {
        if (ctx.session.user.roleId !== 4) {
          return ctx.body = testrecordResponseCode.ONLY_ADMINISTRATOR_CAN_DELETE;
        }
        if (ctx.request.body.id && _.isInteger(ctx.request.body.id)) {
          let id = ctx.request.body.id;
          let isDelete = await TestRecord.deleteById(id);
          if (isDelete) {
            return ctx.body = globalResponseCode.SUCCESS;
          } else {
            return ctx.body = testrecordResponseCode.DELETE_FAILED
          }
        } else {
          return ctx.body = globalResponseCode.PARAMS_ERROR;
        }
      } else {
        return ctx.body = globalResponseCode.NO_LOGIN;
      }
    } catch (error) {
      logTool.logError(ctx, error);
      return ctx.body = globalResponseCode.SYSTEM_EXCEPTION;
    }

  }

  @request('post', '/testrecord/update')
  @tags(['TestRecord'])
  @summary('修改提测单信息')
  @description('1. 只有处理中的订单可修改信息 2.只有提测的开发可以修改')
  @body(
    {
      id: { type: 'int', required: true, example: 1, description: '' },
      newFeatureRemark: { type: 'string', require: false, example: '新功能1 新功能2 新功能3' },
      updateRemark: { type: 'string', require: false, example: '修改点1 修改点2 修改点3' },
      adviseRemark: { type: 'string', require: false, example: '已知问题有...' },
      testPackageUrl: { type: 'string', require: false, example: 'http://mblock.com/dowmload/' }
    }
  )
  async updateTestRecord(ctx) {
    try {
      if (ctx.session.user) {
        let testRecord = ctx.request.body;
        if (!testRecord.id || !_.isInteger(testRecord.id)) {
          return ctx.body = globalResponseCode.PARAMS_ERROR;
        }
        if (_.keys(testRecord).length <= 1) {
          return ctx.body = globalResponseCode.PARAMS_ERROR;
        }
        // 只有提测的开发人员可修改
        let realCreaterId = await TestRecord.queryTestRecordCreater(testRecord.id);
        if (ctx.session.user.id !== realCreaterId) {
          return ctx.body = testrecordResponseCode.ONLY_CREATER_CAN_EDIT;
        }
        let result = await TestRecord.updateInfo(testRecord);
        if (result == 0) {
          return ctx.body = testrecordResponseCode.UPDATE_NOT_AFFECTED;
        } else {
          let testRecordLogId = await TestRecordLog.insert(ctx.session.user, testRecord.id, '修改了提测单', '');
          return ctx.body = globalResponseCode.SUCCESS;
        }
      } else {
        return ctx.body = { code: 10002, data: "Unauthorized!" };
      }
    } catch (error) {
      logTool.logError(ctx, error);
      return ctx.body = globalResponseCode.SYSTEM_EXCEPTION;
    }

  }

  @request('post', '/testrecord/pmCheckPass')
  @tags(['TestRecord'])
  @summary('产品审核通过')
  @body(
    {
      id: { type: 'int', required: true, example: 1, description: '提测单ID' }
    }
  )
  async testReocrdPMCheckPass(ctx) {
    try {
      if (ctx.session.user) {
        if (ctx.session.user.roleId !== 1) {
          return ctx.body = globalResponseCode.NO_AUTH;
        }
        let user = ctx.session.user;

        if (ctx.request.body.id && _.isInteger(ctx.request.body.id)) {
          let testRecordId = ctx.request.body.id;
          let projectId = await TestRecord.queryProjectIdByTestRecordId(testRecordId);
          let isUserInProject = await User.queryIsUserInProject(projectId, user.id);
          if (!isUserInProject) {
            return ctx.body = testrecordResponseCode.USER_NOT_IN_PROJECT;
          }
          let result = await TestRecord.updateStatus(testRecordId, 2);
          if (result == 0) {
            return ctx.body = testrecordResponseCode.PM_CHECK_PASS_FAIL;
          }
          let testRecordLogId = await TestRecordLog.insert(ctx.session.user, testRecordId, '体验通过', '');
          return ctx.body = globalResponseCode.SUCCESS;
        } else {
          return ctx.body = globalResponseCode.PARAMS_ERROR;
        }
      } else {
        return ctx.body = globalResponseCode.NO_LOGIN;
      }
    } catch (error) {
      logTool.logError(ctx, error);
      return ctx.body = globalResponseCode.SYSTEM_EXCEPTION;
    }
  }

  @request('post', '/testrecord/pmCheckFail')
  @tags(['TestRecord'])
  @summary('产品打回')
  @body(
    {
      id: { type: 'int', required: true, example: 1, description: '提测单ID' }
    }
  )
  async testReocrdPMCheckFail(ctx) {
    try {
      if (ctx.session.user) {
        if (ctx.session.user.roleId !== 1) {
          return ctx.body = globalResponseCode.NO_AUTH;
        }
        let user = ctx.session.user;

        if (ctx.request.body.id && _.isInteger(ctx.request.body.id)) {
          let testRecordId = ctx.request.body.id;
          let backreason = ctx.request.body.reason;
          let projectId = await TestRecord.queryProjectIdByTestRecordId(testRecordId);
          let isUserInProject = await User.queryIsUserInProject(projectId, user.id);
          if (!isUserInProject) {
            return ctx.body = testrecordResponseCode.USER_NOT_IN_PROJECT;
          }
          let result = await TestRecord.updateStatus(testRecordId, 3);
          if (result == 0) {
            return ctx.body = testrecordResponseCode.PM_CHECK_BACK_FAIL;
          }
          let testRecordLogId = await TestRecordLog.insert(ctx.session.user, testRecordId, '产品体验打回', backreason);
          return ctx.body = globalResponseCode.SUCCESS;
        } else {
          return ctx.body = globalResponseCode.PARAMS_ERROR;
        }
      } else {
        return ctx.body = globalResponseCode.NO_LOGIN;
      }
    } catch (error) {
      logTool.logError(ctx, error);
      return ctx.body = globalResponseCode.SYSTEM_EXCEPTION;
    }
  }

  @request('post', '/testrecord/testCheckPass')
  @tags(['TestRecord'])
  @summary('测试审核通过')
  @body(
    {
      id: { type: 'int', required: true, example: 1, description: '提测单ID' }
    }
  )
  async testRecordTestCheckPass(ctx) {
    try {
      if (ctx.session.user) {
        if (ctx.session.user.roleId !== 3) {
          return ctx.body = globalResponseCode.NO_AUTH;
        }
        let user = ctx.session.user;

        if (ctx.request.body.id && _.isInteger(ctx.request.body.id)) {
          let testRecordId = ctx.request.body.id;
          let projectId = await TestRecord.queryProjectIdByTestRecordId(testRecordId);
          let isUserInProject = await User.queryIsUserInProject(projectId, user.id);
          if (!isUserInProject) {
            return ctx.body = testrecordResponseCode.USER_NOT_IN_PROJECT;
          }
          let count = await TestRecord.queryTestStatus(testRecordId);
          if(count ===0){
             let res  = await TestReport.updateTestStartTime(testRecordId); 
          }
          let result = await TestRecord.updateStatus(testRecordId, 5);
          if (result == 0) {
            return ctx.body = testrecordResponseCode.TESTER_CHECK_PASS_FAIL;
          }
          let testRecordLogId = await TestRecordLog.insert(ctx.session.user, testRecordId, '测试审核通过', '');
          return ctx.body = globalResponseCode.SUCCESS;
        } else {
          return ctx.body = globalResponseCode.PARAMS_ERROR;
        }
      } else {
        return ctx.body = globalResponseCode.NO_LOGIN;
      }
    } catch (error) {
      logTool.logError(ctx, error);
      return ctx.body = globalResponseCode.SYSTEM_EXCEPTION;
    }
  }

  @request('post', '/testrecord/testCheckFail')
  @tags(['TestRecord'])
  @summary('测试打回')
  @body(
    {
      id: { type: 'int', required: true, example: 1, description: '提测单ID' }
    }
  )
  async testRecordTestCheckFail(ctx) {
    try {
      if (ctx.session.user) {
        if (ctx.session.user.roleId !== 3) {
          return ctx.body = globalResponseCode.NO_AUTH;
        }
        let user = ctx.session.user;

        if (ctx.request.body.id && _.isInteger(ctx.request.body.id)) {
          let testRecordId = ctx.request.body.id;
          let backreason = ctx.request.body.reason;
          let projectId = await TestRecord.queryProjectIdByTestRecordId(testRecordId);
          let isUserInProject = await User.queryIsUserInProject(projectId, user.id);
          if (!isUserInProject) {
            return ctx.body = testrecordResponseCode.USER_NOT_IN_PROJECT;
          }
          let result = await TestRecord.updateStatus(testRecordId, 4);
          if (result == 0) {
            return ctx.body = testrecordResponseCode.TESTER_CHECK_BACK_FAIL;
          }
          let testRecordLogId = await TestRecordLog.insert(ctx.session.user, testRecordId, '测试打回', backreason);
          return ctx.body = globalResponseCode.SUCCESS;
        } else {
          return ctx.body = globalResponseCode.PARAMS_ERROR;
        }
      } else {
        return ctx.body = globalResponseCode.NO_LOGIN;
      }
    } catch (error) {
      logTool.logError(ctx, error);
      return ctx.body = globalResponseCode.SYSTEM_EXCEPTION;
    }
  }

  @request('post', '/testrecord/activeList')
  @tags(['TestRecord'])
  @summary('根据版本查询最新激活的提测记录列表')
  @body({
		page: { type: 'int', required: true, example: 1 },
		size: { type: 'int', required: true, example: 10 },
	})
  async getActiveRecordList(ctx) {
    try {
      if (ctx.session.user) {
        let condition = ctx.request.body;
        if (!condition || !condition.page || !condition.size || !_.isInteger(condition.page) || !_.isInteger(condition.size)) {
          return ctx.body = globalResponseCode.PARAMS_ERROR;
        }
        if (condition.page < 1 || condition.size < 1) {
          return ctx.body = globalResponseCode.PARAMS_ERROR;
        }
        let result = await TestRecord.getActiveTestRecordList(condition);
        return ctx.body = _.merge({}, globalResponseCode.SUCCESS, { data: result });
      } else {
        return ctx.body = globalResponseCode.NO_LOGIN;
      }
    } catch (error) {
      logTool.logError(ctx, error);
      return ctx.body = globalResponseCode.SYSTEM_EXCEPTION;
    }
  }

  @request('post', '/testrecord/active')
  @tags(['TestRecord'])
  @summary('查询版本的当前提测信息')
  @description(`testStatu: 1=产品体验中 2=测试审核中 3=产品打回 4=测试打回 5=测试审核通过（测试完成）`)
  @body({
    versionId: { type: 'int', required: true, example: 1 }
  })
  async getActiveRecord(ctx) {
    try {
      if (ctx.session.user) {
        if (ctx.request.body.versionId && _.isInteger(ctx.request.body.versionId)) {
          let versionId = ctx.request.body.versionId;
          let version = await Versoin.queryVersionById(versionId);
          let users = [];
          let delayTime = 0;
          let historyRecordList = [];
          let lastTestRecord = [];
          let recordLog = [];
          if (!_.isEmpty(version)) {
            historyRecordList = await TestRecord.getRecordListByVersionId(versionId);
            lastTestRecord = await TestRecord.queryLastTestRecordByVersionId(versionId);
            if (!_.isEmpty(lastTestRecord)) {
              recordLog = await TestRecordLog.queryRecordLogByTestRecordId(lastTestRecord.id);
            }
            users = await User.queryUsersByProjectId(version.projectId);
            let firstTestRecord = await TestRecord.queryFirstTestRecordByVersionId(versionId);
            if (!_.isEmpty(firstTestRecord)) {
              let m2 = moment(firstTestRecord.testCreateTime);
              let m1 = moment(version.expectTestTime);
             
              delayTime = moment.duration(m2.diff(m1)).asDays();
              delayTime = Math.floor(delayTime * 10) / 10;
            }
            if(!_.isEmpty(historyRecordList)){
              lastTestRecord = _.merge( historyRecordList[0], lastTestRecord);
              historyRecordList[0] = {...lastTestRecord, recordLog: recordLog};
            }

            return ctx.body = _.merge({}, globalResponseCode.SUCCESS, 
              { data: { version: {...version, testDelayTime : delayTime}, users: users, 
                 testRecordList: historyRecordList,lastTestRecord } });
          }else{
            return ctx.body = testrecordResponseCode.RECORD_VERSION_NOT_EXISTS;
          }
        } else {
          return ctx.body = globalResponseCode.PARAMS_ERROR;
        }
      } else {
        return ctx.body = globalResponseCode.NO_LOGIN;
      }
    } catch (error) {
      logTool.logError(ctx, error);
      return ctx.body = globalResponseCode.SYSTEM_EXCEPTION;
    }
  }

  @request('post', '/testrecord/info')
  @tags(['TestRecord'])
  @summary('查询版本信息（根据提测ID）')
  @body({
    id: { type: 'int', required: true, example: 1 ,description:'提测记录ID'}
  })
  async getTestRecordInfo(ctx){
    try {
      if(ctx.session.user){
        if(ctx.request.body.id && _.isInteger(ctx.request.body.id)){
          let testRecordId = ctx.request.body.id;
          let testRecord = await TestRecord.queryTestRecordById(testRecordId);
          if(_.isEmpty(testRecord)){
            return ctx.body = testrecordResponseCode.TEST_RECORD_NOT_EXIST;
          }
          let recordLog = await TestRecordLog.queryRecordLogByTestRecordId(testRecordId);
          return ctx.body = _.merge({}, globalResponseCode.SUCCESS, 
            {data:{testRecord: testRecord, recordLog: recordLog }});
        }else{
          return ctx.body = globalResponseCode.PARAMS_ERROR;
        }
      }else{
        return ctx.body = globalResponseCode.NO_LOGIN;
      }
    } catch (error) {
      logTool.logError(ctx, error);
      return ctx.body = globalResponseCode.SYSTEM_EXCEPTION;
    }
  }

  @request('post','/testrecord/sendNews')
  @tags(['TestRecord'])
  @summary('向钉钉发送提示消息')
  @body({
    webhook:{ type :'string',requird: true,example:'https://oapi.dingtalk.com/robot/send?access_token=xxx',description:'钉钉机器人接口地址'},
    news:{type:'json',requird:true,description:'消息类型及内容'}          
  })
  async sendNews(ctx){
    try{
      if(ctx.session.user){
        if(ctx.request.body.projectName && ctx.request.body.news){
          let name = ctx.request.body.projectName;
          let url = await Project.getWebhook(name)
          if(url === ''){
            return ctx.body = testrecordResponseCode.WEBHOOK_NOT_EXISTS
          }else{
            let data = ctx.request.body.news
            let newslog = await TestRecord.httprequest(url,data);
            return ctx.body = globalResponseCode.SUCCESS
          } 
        }else{
          return ctx.body = globalResponseCode.PARAMS_ERROR;
        }
      }else{
        return ctx.body = globalResponseCode.NO_LOGIN;
      }
    }catch(error){
      console.log('err..',error)
      logTool.logError(ctx, error);
      return ctx.body = globalResponseCode.SYSTEM_EXCEPTION;
    }
  }

  @request('post','/testrecord/getTestCount')
  @tags(['TestRecord'])
  @summary('获取提测次数')
  @body({
    pname:'项目名称'         
  })
  async getProjectTestCount(ctx){
    try{
      if(ctx.session.user){
        let pname = ctx.request.body.pname
        if(pname){
          let result = await TestRecord.getTestCount(pname)
          return ctx.body = _.merge({}, globalResponseCode.SUCCESS, 
            {data:result});
        }else{
          return ctx.body = globalResponseCode.PARAMS_ERROR;
        }
      }else{
        return ctx.body = globalResponseCode.NO_LOGIN;
      }
    }catch(error){
      console.log(error)
      logTool.logError(ctx, error);
      return ctx.body = globalResponseCode.SYSTEM_EXCEPTION;
    }
  }

  @request('post','/testrecord/getSuccessRate')
  @tags(['TestRecord'])
  @summary('获取提测成功率')
  @body({
    pname:'项目名称'         
  })
  async getLaunchTestSuccessRate(ctx){
    try{
      if(ctx.session.user){
        let pname = ctx.request.body.pname
        if(pname){
          let result = await TestRecord.launchTestSuccessRate(pname)
          return ctx.body = _.merge({}, globalResponseCode.SUCCESS, 
            {data:result});
        }else{
          return ctx.body = globalResponseCode.PARAMS_ERROR;
        }
      }else{
        return ctx.body = globalResponseCode.NO_LOGIN;
      }
    }catch(error){
      console.log(error)
      logTool.logError(ctx, error);
      return ctx.body = globalResponseCode.SYSTEM_EXCEPTION;
    }
  }
  
}

module.exports = new TestSheetController();